package org.naive.vstream.render;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;

import org.naive.vstream.ReconstructionPlan;

public class Main {

	public static void main(String[] args) throws IOException {
		final JFrame f = new JFrame();
		f.setSize(512, 512);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		final BufferedImage bi = new BufferedImage(512, 512, BufferedImage.TYPE_BYTE_GRAY);
		final WritableRaster raster = bi.getRaster();
		AbstractRenderer ar = new AbstractRenderer(bi.getWidth(), bi.getHeight()) {

			@Override
			protected void outPixel(int x, int y, int brightness) {
				raster.setSample(x, y, 0, (brightness * 255) / 16);
				f.repaint();
			}
		};
		f.add(new JComponent() {
			@Override
			protected void paintComponent(Graphics g) {
				g.drawImage(bi, 0, 0, null);
			}
		});
		f.setVisible(true);
		ar.loop(new ByteArrayInputStream(generate().toByteArray()));
	}

	private static int checkUniform(Raster rast, int x, int y, int w, int h) {
		final int value = readPixel(rast, x, y);
//		if (w==1&& h==1) {
//			return value;
//		} else {
//			return -1;
//		}
		for (int yy = y; yy < y + h; yy++) {
			for (int xx = x; xx < x + w; xx++) {
				final int v = readPixel(rast, xx, yy);
				if (Math.abs(value - v) > 10) {
					return -1;
				}
			}
		}
		return value;
	}

	private static int readPixel(Raster rast, int x, int y) {
		return (rast.getWidth() > x && rast.getHeight() > y) ? rast.getSample(x, y, 0) : 0;
	}

	private static void iterate(ReconstructionPlan rp, Raster rast, boolean open, int x, int y, int w, int h)
			throws IOException {
		final int checkUniform = checkUniform(rast, x, y, w, h);
		if (!open) {
			rp.open();
		}
		if (checkUniform >= 0) {
			rp.skip();
			rp.skip();
			rp.skip();
			rp.skip();

			rp.brightness(checkUniform * 16 / 255);
		}
		else {
			
			iterate(rp, rast, false, x, y, w / 2, h / 2);
			iterate(rp, rast, false, x + w / 2, y, w / 2, h / 2);
			iterate(rp, rast, false, x, y + h / 2, w / 2, h / 2);
			iterate(rp, rast, false, x + w / 2, y + h / 2, w / 2, h / 2);
		}

	}

	private static ByteArrayOutputStream generate() throws IOException {
		BufferedImage img = ImageIO.read(new File("/Users/andrew/Projects/eagle.png"));
		Raster imgR = img.getRaster();

		final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		final ReconstructionPlan quadWriter = new ReconstructionPlan(byteArrayOutputStream);
		iterate(quadWriter, imgR, true, 0, 0, 512, 512);
		return byteArrayOutputStream;
	}
	
//	private static ByteArrayOutputStream generate1() throws IOException {
//		final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//		final ReconstructionPlan quadWriter = new ReconstructionPlan(byteArrayOutputStream);
//
//		quadWriter.open();
//
//		quadWriter.open();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.skip();
//		quadWriter.open();
//
//		quadWriter.open();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.open();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//
//		quadWriter.skip();
//		quadWriter.skip();
//
//		quadWriter.open();
//
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//		quadWriter.skip();
//
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//		quadWriter.open();
//
//		quadWriter.close();
//		return byteArrayOutputStream;
//	}

}
